/**
 * @file hash_table.h
 * Definition file for a generic HashMap data structure
 * This HashMap use open adressing methods. Hash function can be changed,
 * default use MAD method.
 * The load factor is always kept less than 0.5. When the load factor reaches
 * 0.5, the entries are rehashed into a new bucket array with twice the
 * capacity.
 *
 * @author Simon Vernhes
 * @ingroup HashMap
 *
 * @todo Implementation !
 * @todo Documentation
 * @todo Comment functions.
 * @todo Check return value of the functions
 */
#ifndef HASHTABLE_H
#define HASHTABLE_H

#include <yadl_common.h>
#include <pair.h>
#include <array_list.h>
#include <stdlib.h>

/** Default initial capacity  */
#define HASHTABLE_DEFAULT_CAPACITY 512

#define HASHTABLE_OK  1
#define HASHTABLE_NOK 0

/** Type of hash function */
typedef int (*hash_function_t) (int, void*);
/** Type of equal function */
typedef int (*equal_t) (void*, void*);

/** The generic HashMap data structure */
struct hash_table {
	/** Hash Function */
	hash_function_t hash;
	/** Equal Function : on keys */
	equal_t equal;
	/** A destructor for the keys of the HashTable */
	destructor_t del_key;
	/** A destructor for the elements of the HashTable */
	destructor_t del_value;

	/** The current number of elements inside the HashMap */
	int size;
	/** The current capacity of the array containing the elements of the HashMap */
	int capacity;
	/** The array containing the elements of the HashMap */
	pair** buckets;
};

/** The HashMap object */
typedef struct hash_table* hash_table;

hash_table hash_table_new();
void hash_table_free(hash_table);
void hash_table_set_hash_function(hash_table, hash_function_t);

int hash_table_size(hash_table);
int hash_table_is_empty(hash_table);

int hash_table_put(hash_table, void*, void*);
pair* hash_table_get_pair(hash_table, void*);
void* hash_table_get(hash_table, void*);
void* hash_table_remove(hash_table, void*);

array_list hash_table_get_keys(hash_table);
array_list hash_table_get_values(hash_table);

#endif

